package com.personal.persistence.sqlSession;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.List;

import com.personal.persistence.pojo.Configuration;
import com.personal.persistence.pojo.MappedStatement;

public class DefaultSqlSession implements SqlSession {
    private final Configuration configuration;

    public DefaultSqlSession(Configuration configuration) {
        this.configuration = configuration;
    }

    @Override
    public <T> List<T> findAll(String statementId, Object... params) throws Exception {
        Executor executor = new SimpleExecutor();
        MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
        return executor.query(configuration, mappedStatement, params);
    }

    @Override
    public <E> E findByCondition(String statementId, Object... params) throws Exception {
        List<E> objects = findAll(statementId, params);
        if (objects.size() == 1) {
            return objects.get(0);
        }
        throw new RuntimeException("查询结果为空或返回结果过多。");
    }

    @Override
    public <T> T getMapper(Class<?> mapperClass) {
        //noinspection unchecked
        return (T) Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{mapperClass}, (proxy, method, args) -> {
            String methodName = method.getName();
            String className = method.getDeclaringClass().getName();
            String statementId = className + "." + methodName;
            Type genericReturnType = method.getGenericReturnType();
            if (genericReturnType instanceof ParameterizedType) {
                return findAll(statementId, args);
            }
            return findByCondition(statementId, args);
        });
    }
}
